#include "Logic.h"
#include"Player.h"


//void Logic::continueUntilPause()
//{
//  while(doTick()){};
//}

/* Handle upkeep of battle. */
void Logic::doBattle()
{
  /* Make sure all players have a card active. */
  if(table->activeCards.size() < table->players.size()) return;
  vector<Player*> tie = evaluateTable();
  /* If not a tie, just return winner. */
  if(tie.size() == 1)
  {
    table->soloMover = tie.at(0);
    giveBattleReward(tie.at(0));
  }
  /* WAR! */
  else
  {
    table->warTime = true;
    /* Tax involved players. */
    for(int i = 0; i < tie.size(); ++i)
    {
      taxPlayer(tie.at(i), 3);
      tie.at(i)->setWarFlag(true);
    }
  }
}

void Logic::doWar()
{
  /* Abort if there's a player who's not in yet. */
  for(int i=0; i<table->players.size();++i)
    if(table->players.at(i).getWarFlag() == true) return;
  /* See if we have another tie. */
  vector<Player*> tie = evaluateTable();
  /* If not a tie, just return winner. */
  if(tie.size() == 1)
  {
    giveBattleReward(tie.at(0));
    /* Peace! */
    table->warTime = false;
  }
  /* WAR (again!) */
  else
  {
    /* Tax involved players. */
    for(int i = 0; i < tie.size(); ++i)
    {
      taxPlayer(tie.at(i), 3);
      tie.at(i)->setWarFlag(true);
    }
  }
}

//bool Logic::doBattle()
//{
//  /* Make sure all players have a card active. */
//  if(table->activeCards.size() < table->players.size()) return false;
//  vector<Player*> tie = evaluateTable();
//  /* If not a tie, just return winner. */
//  if(tie.size() == 1)
//  {
//    table->soloMover = tie.at(0);
//    giveBattleReward(tie.at(0));
//    doBattle();
//  }
//  /* If war time. */
//  else
//  {
//  }
//}
Deck Logic::getActives() 
{ 
  return table->activeCards; 
} 
int Logic::getGameWinner() 
{ 
  int foundPlayer = -1;
  /* Winning player is the only player with a deck. */
  for(int i = 0; i < table->players.size(); ++i)
  {
    if(table->players.at(i).getArmy()->size() != 0)
    {
      /* Fail if multiple winners still. */
      if(foundPlayer != -1)
      {
        return -1;
      }
      foundPlayer = i;
    }
  }
  /* If no issue, return winner. */
  return foundPlayer;
} 

set<Player*> Logic::getMovingPlayers() 
{ 
  set<Player*> result;
  if(table->warTime){}
  else
  {
    result.insert(table->soloMover);
  }
  return result;
}

set<Player*> Logic::getWarringPlayers() 
{
  vector<Player*> winnersOfRound = evaluateTable();
  if(winnersOfRound.size() > 1){
	return set<Player*>  (winnersOfRound.begin(), winnersOfRound.end());
  }
  else{
        return set<Player*>();
  }  
}
 
void Logic::processSoloMove()
{
  /* Move to next player */
  for(int i = 0; i < table->players.size(); ++i)
  {
    if(&table->players.at(i) == table->soloMover)
    {
      taxPlayer(table->soloMover, 1); 
      table->soloMover = &table->players.at((i+1)%(table->players.size()));
    }
  }
}
void Logic::removeSpoils() 
{ 
  /* Draw all cards. */
  table->spoilsPile.draw(table->spoilsPile.size());
} 

void Logic::setActive(Card* card, Player* player) 
{ 
  /* NEEDS TESTING */ 
  for(int i = 0; i < table->activeCards.size(); ++i) 
  { 
    if(table->activeCards.at(i)->getOwner() == player) 
    { 
      /* Move card to the pillage pile. */
      table->pillagePile.add(table->activeCards.at(i));
      /* Replace the original. */
      table->activeCards.replace(i, card);
      return;
    } 
  } 
  table->activeCards.add(card);
}
void Logic::setTable(Table* t) 
{ 
  table = t;
} 
void Logic::taxPlayer(Player* taxMe, int numberOfCards) 
{
  taxMe->getArmy()->transfer(numberOfCards, &table->spoilsPile);
} 
bool Logic::doTick() 
{
  if(!table->warTime)
  {
    /* If soloMover has made their move... */
    if(table->soloMover->getMoveCard() != NULL)
    {
      /* increment solomover and tax. */
      processSoloMove();
      /* See if the battle gets anywhere. */
      doBattle();
    }
  }
  else
  {
    doWar();
  }
} 
/* Returns the set of tieing players. */
vector<Player*> Logic::evaluateTable() 
{
  vector<Player*> result;
  /* Do ace check if at war. */
  if(table->warTime)
  {
    /* Search pile for aces, put owners in result. */
    for(int i = 0; i < table->activeCards.size(); ++i)
    {
      if(table->activeCards.at(i)->getRank() == ace)
      {
        result.push_back(table->activeCards.at(i)->getOwner());
      }
    }
    /* If at least one ace in pile, return result. */
    if(!result.empty()) return result;
  }
  /* Sort activeCards deck */
  table->activeCards.sort();
  /* Get best card in deck. */
  Card* best = table->activeCards.at(table->activeCards.size()-1);
  /* Iterate backwards until you find one that doesn't tie with best. */
  for(int i = table->activeCards.size()-1; i >= 0; --i)
  {
    if(best->compareCard(*table->activeCards.at(i)) == 0)
    {
      result.push_back(table->activeCards.at(i)->getOwner());
    }
    else break;
  }
  /* Return vector. */
  return result;
} 
void Logic::giveBattleReward(Player* winner) 
{
  /*add all cards on table to player's deck*/
  Deck* reward;
  reward->add(&table->pillagePile);
  reward->add(&table->activeCards);
  reward->shuffle();
  winner->getArmy()->add(reward);
}
